package ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.imp;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.devicecontroller.DeviceChangeListener;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.devicecontroller.DeviceManager;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.persistence.DeviceDAO;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.persistence.model.Device;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.AlarmService;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.CompoundCommandService;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.DeviceService;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.FieldService;
import ar.edu.utn.frsf.proyectofinal.sistemadecontrolmodbus.service.SimpleCommandService;

public class DeviceServiceImp implements DeviceService, DeviceChangeListener {

	//TODO: completo
	private Device device;
	private DeviceDAO devDAO;
	
	private DeviceManager deviceman; 
	private List<DeviceChangeListener> deviceListeners;
	
	private List<FieldService> fieldServices;
	private List<SimpleCommandService> simpleCommandServices;
	private List<CompoundCommandService> compoundCommandService;
	private List<AlarmService> alarmServices;
	
	public DeviceServiceImp(){
		deviceListeners = new ArrayList<DeviceChangeListener>();
	}
	@Override
	public String getDeviceName() {
		return device.getName();
	}

	@Override
	public String getDeviceType() {
		return devDAO.getDeviceTypeName(device);
	}

	@Override
	public ConnectionState getDeviceState() {
		switch(deviceman.getState()){
		case CONNECTED:
			return ConnectionState.CONNECTED;
		case DISCONNECTED:
			return ConnectionState.DISCONNECTED;
		case TRYING_CONNECTION:
			return ConnectionState.TRYING;
		case WAITING_CONNECTION:
			return ConnectionState.WAITING;
		default:
			break;
		
		}
		return null;
	}

	@Override
	public Date getLastDate() {
		return devDAO.getLastActivity(device);
	}

	@Override
	public synchronized void connect() {
		if(getDeviceState() == ConnectionState.DISCONNECTED)
			deviceman.connect();
	}

	@Override
	public synchronized void disconnect() {
		if(getDeviceState() == ConnectionState.CONNECTED)
			deviceman.disconnect();
	}

	@Override
	public String getDescription() {
		return device.getDescription();
	}

	@Override
	public Integer getSoundingtime() {
		return device.getSoundingTime();
	}

	@Override
	public List<FieldService> getFieldsService() {
		return fieldServices;
	}

	@Override
	public List<AlarmService> getDeviceAlarmsService() {
		return alarmServices;
	}

	@Override
	public List<CompoundCommandService> getCompoundCommandsService() {
		return compoundCommandService;
	}

	@Override
	public List<SimpleCommandService> getSimpleCommandsService() {
		return simpleCommandServices;
	}

	@Override
	public List<AlarmService> getActiveDeviceAlarmsService() {
		List<AlarmService> ret = new ArrayList<AlarmService>();
		for (AlarmService alms : getDeviceAlarmsService()) {
			if(alms.isActive())
				ret.add(alms);
		}
		return ret;
	}
	/**
	 * @return the device
	 */
	public Device getDevice() {
		return device;
	}

	/**
	 * @param device the device to set
	 */
	public void setDevice(Device device) {
		this.device = device;
	}

	/**
	 * @return the deviceman
	 */
	public DeviceManager getDeviceman() {
		return deviceman;
	}

	/**
	 * @param deviceman the deviceman to set
	 */
	public void setDeviceman(DeviceManager deviceman) {
		this.deviceman = deviceman;
	}

	@Override
	public Integer getDeviceID() {
		return device.getID();
	}
	@Override
	public void addDeviceChangeListener(DeviceChangeListener devlistener) {
		deviceListeners.add(devlistener);
	}
	@Override
	public void changeState() {
		//TODO: Actualizar estado guardarlo en la base de datos y actualizar el objeto device
		if(deviceman.isConnected())
			devDAO.setLastActivity(device,new Date());
		for (DeviceChangeListener lis : deviceListeners) {
			lis.changeState();
		}
		
	}
	@Override
	public boolean getAutoActualization() {
		return device.getAutoActualization();
	}
	/**
	 * @return the devDAO
	 */
	public DeviceDAO getDevDAO() {
		return devDAO;
	}
	/**
	 * @param devDAO the devDAO to set
	 */
	public void setDevDAO(DeviceDAO devDAO) {
		this.devDAO = devDAO;
	}
	public void setFieldsService(List<FieldService> fieldServices) {
		this.fieldServices = fieldServices;
	}
	public void setActiveDeviceAlarmsService(List<AlarmService> alarmServices) {
		this.alarmServices = alarmServices;
	}
	public void setCompoundCommandsService(	List<CompoundCommandService> compoundCommandService) {
		this.compoundCommandService = compoundCommandService;
	}
	public void setSimpleCommandsService(
			List<SimpleCommandService> simpleCommandServices) {
		this.simpleCommandServices = simpleCommandServices;
		
	}
	@Override
	public void shutDown() {
		disconnect();		
	}


}
